package structures;

import java.sql.Time;
import java.util.ArrayList;
import java.util.Map.Entry;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import javax.swing.table.AbstractTableModel;

/**
 * @author darin
 *
 */
public class TaskTableModel extends AbstractTableModel {

	private static final int MILISECONDS_IN_A_DAY = 60*60*1000;
	/**
	 * Holds the rows.
	 */
	private ArrayList<Task> data;
	
	/**
	 * Since this is strictly a TaskTableModel I can hard-code the 
	 * column names
	 */
	private String[] colNames = {"Task ID", "Task Date", "Time In",
			"Time Out", "Type", "SubType", "Description",
			"Total Time"};


	SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
	SimpleDateFormat timeFormatter = new SimpleDateFormat("hh:mm:ss");
	/**
	 * @param taskList an arrayList of tasks (rows in the table).
	 *
	 */
	public TaskTableModel(final ArrayList<Task> taskList) {
		data = taskList;
		// add an extra row for creating new records
		Task newTask = new Task();
		taskList.add(newTask);
	}
	/* (non-Javadoc)
	 * @see javax.swing.table.TableModel#getRowCount()
	 */
	@Override
	public final int getRowCount() {
		// TODO Auto-generated method stub
		return data.size();
	}

	@Override
	public final int getColumnCount() {

		return 8; // magic number cuz I know I want 8 columns...can't count fiels
	}

	/* (non-Javadoc)
	 * @see javax.swing.table.TableModel#getValueAt(int, int)
	 */
	@Override
	public final Object getValueAt(int rowIndex, int columnIndex) {
		Task task = data.get(rowIndex);
		switch(columnIndex) {
		case 0:
			return task.getTaskId();
		case 1:
			return task.getTaskDate();
		case 2: 
			return task.getTimeIn();
		case 3:
			return task.getTimeOut();
		case 4:
			return task.getType();
		case 5:
			return task.getSubtype();
		case 6: 
			return task.getTaskDesc();
		case 7:
			if(task.getTimeIn() !=null)
			return (double) (task.getTimeOut().getTime()
					- task.getTimeIn().getTime())
					/ MILISECONDS_IN_A_DAY;
			
		}
		return null;
	}

	/*
	 *  How to update changes to a task? -- inclusion of this method comes from
	 *  MyTableModel.java
	 */
	public void setValueAt(Object value, int rowIndex, int columnIndex)
	{
		Task task = data.get(rowIndex);
		switch(columnIndex) {
		// will have to turn string to date
		case 1: Date newDate = null; 
			try {
				newDate = new Date(dateFormatter.parse((String)value).getTime());
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
				task.setTaskDate(newDate);
			break;
			// will have to turn string to time
		case 2: Time newTime = null;
			try {
				newTime = new Time(timeFormatter.parse((String)value).getTime());
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			task.setTimeIn(newTime);
			break;
			// will have to turn strin to time
		case 3: Time newTimeOut = null;
		try {
			newTimeOut = new Time(timeFormatter.parse((String)value).getTime());
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		task.setTimeOut(newTimeOut);
		break;
			//must limit to allowed values
		case 4: 
				if(value instanceof String)
				{
					// save the string
					// send the string to the db (except table doesn't know about model)
					// could throw an exception to the ui with the string as a message
					// and have the ui create a dialog (add string?) and send to 
					// db for add, then reload the list.
					// reload the list
					System.out.println("You typed in something new (TaskTableModel line 130)");
				}
				else
			task.setType((int) ((Entry<Integer, String>) value).getKey());
			break;
			 // must limit to allowed values
		case 5:	task.setSubtype((int)((Entry)value).getKey());
			break;
		case 6: task.setTaskDesc((String)value);
			break;
		case 7: // 7 is calculated from times, not editable
			break;
		default:
			break;
		}
		fireTableCellUpdated(rowIndex, columnIndex);
	}

	/**
	 * 
	 * @return an arraylist of tasks
	 */
	public final ArrayList<Task> getData() {
		return data;
	}
	/**
	 * 
	 * @param newData an arrayList of tasks
	 */
	public final void setData(final ArrayList<Task> newData) {
		data = newData;
	}
	/**
	 * 
	 * @return column names
	 */
	public final String[] getColumnNames() {
		return colNames;
	}
	/**
	 * 
	 * @param names column names
	 */
	public final void setColumnNames(final String[] names) {
		colNames = names;
	}
	/**
	 * @param col a column
	 * @return the name of a col
	 */
	@Override
	public final String getColumnName(final int col) {
		  return colNames[col];
		}
	/**
	 * @param row the cells row
	 * @param col the cells col
	 * @return true or false if the cell is editable
	 */
	@Override
	 public final boolean isCellEditable(final int row, final int col) {
	        //Note that the data/cell address is constant,
	        //no matter where the cell appears onscreen.
	        if (col < 1 || col == 7) {
	            return false;
	        } else {
	            return true;
	        }
	    }

}